package com.qf.aop.impl;

import com.qf.aop.annocation.FormToken;
import com.qf.common.BusinessException;
import com.qf.common.ExceptionStatus;
import com.qf.domain.User;
import com.qf.feign.api.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.stream.Stream;

@Slf4j
@Component
@Aspect
public class FormTokenAop {

    @Autowired(required = false)
    private TokenService tokenService;

    // checkToken在加了@FormToken注解的方法之前执行
    @Around("@annotation(formToken)")
    public Object checkToken(ProceedingJoinPoint point, FormToken formToken) throws Throwable {

        log.debug("fromToken");
        // 1.获取表单传递的token
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();

        // 2.从请求对象中获取_form-token
//        String token = request.getParameter("_form-token");

        // 3.获取到目标方法形参
        Object[] args = point.getArgs();

        com.qf.form.FormToken token = null;
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof com.qf.form.FormToken) {
                    token = (com.qf.form.FormToken) args[i];
                    break;
                }
            }
        }

        if(tokenService !=null){
            // 4. 验证token
            Integer code = tokenService.checkToken(token.getFormToken());
            if (code == 1) {
                log.warn("token有误"); // 记录日志
                throw new BusinessException(ExceptionStatus.UNDEFINE_TOEKN); // 抛出异常给用户
            } else if (code == 2) {
                log.warn("token已失效"); // 记录日志
                throw new BusinessException(ExceptionStatus.FAILURE_TOEKN); // 抛出异常给用户
            }
        }

        // 5.token验证成功
        Object proceed = point.proceed(point.getArgs()); // 接着往下调用

        return proceed;

    }
}
